package com.xgpro.common.dingtalk.service.contact.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.xgpro.common.dingtalk.service.contact.DDUserService;
import com.xgpro.common.dingtalk.util.HttpHelper;
import com.xgpro.common.utils.TimeUtil;
import com.xgpro.domain.rolemanage.dto.UserDTO;
import com.xgpro.domain.rolemanage.entity.Department;
import com.xgpro.domain.studycentre.entity.Edu;
import com.xgpro.domain.talentintroduction.entity.User;
import com.xgpro.mapper.rolemanage.DepartmentMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @program: xgpro__dev
 * @description: 钉钉
 * @author: likai
 * @create: 2019-10-10 00:40
 **/

@Service
public class DDUserServiceImpl implements DDUserService {

    private static final String CREATE_USER_URL = "https://oapi.dingtalk.com/user/create?access_token=ACCESSTOKEN";
    private static final String GET_DEPARTMENTUSER_URL = "https://oapi.dingtalk.com/user/simplelist?access_token=ACCESSTOKEN&department_id=DEPARTMENTID";
    private static final String GET_USERINFO_BYCODE_URL = "https://oapi.dingtalk.com/user/getuserinfo?access_token=ACCESSTOKEN&code=CODE";

    @Resource
    private DepartmentMapper departmentMapper;

    /**
     * 1.创建用户
     *
     * @param accessToken
     * @param user
     * @return
     * @throws Exception String
     * @desc ：
     */
    public String createUser(String accessToken, User user) throws Exception {
        //1.准备POST请求参数
        Object data = JSON.toJSON(user);
        System.out.println(data);

        //2.获取请求url
        String url = CREATE_USER_URL.replace("ACCESSTOKEN", accessToken);

        //3.发起POST请求，获取返回结果
        JSONObject jsonObject = HttpHelper.httpPost(url, data);
        System.out.println("jsonObject:" + jsonObject.toString());

        //4.解析结果，获取UserId
        String userId = "";
        if (null != jsonObject) {
            userId = jsonObject.getString("userid");
            //5.错误消息处理
            if (0 != jsonObject.getInteger("errcode")) {
                int errCode = jsonObject.getInteger("errcode");
                String errMsg = jsonObject.getString("errmsg");
                throw new Exception("error code:" + errCode + ", error message:" + errMsg);
            }
        }

        return userId;
    }


    /**
     * 2.根据userid获取成员详情
     *
     * @param accessToken
     * @param userId      void
     * @throws Exception
     * @desc ：获取成员详情
     */
    public UserDTO getUser(String accessToken, String userId) throws Exception {

        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userId);
        request.setHttpMethod("GET");
        OapiUserGetResponse response = client.execute(request, accessToken);


        UserDTO user = new UserDTO();
        user.setUsername(response.getName());
        List<Long> department = response.getDepartment();
        System.out.println(response.getName() + "的部门字符串 getDepartmentUserDetail:" + department);

        long deptId = department.get(department.size() - 1);
        int departId = (int)deptId;

        deptId = deptId == -1 ? 1 : deptId;
        user.setDeptId(departId);
        //封装二级部门，如果没有二级部门，则封装一级部门

        Integer threeDeptId = getSecondDeptId(departId);
        user.setSecondDeptId(threeDeptId);

        user.setDeptId(departId);
        user.setUserId(response.getUserid());
        user.setPhone(response.getMobile());
        user.setMail(response.getEmail());

        Date date = response.getHiredDate();
        if (!ObjectUtils.isEmpty(date)) {
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            Instant instant = date.toInstant();
            ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
            LocalDate localDate = zonedDateTime.toLocalDate();
            String format = localDate.format(timeFormatter);
            user.setHiredDate(format);

            int days = TimeUtil.getDifferentDays(date, new Date());
            String years = String.format("%.2f", Double.valueOf(days) / 365.0);
            user.setJobTime(years);
        }
        user.setPhoto(response.getAvatar());
        user.setJob(response.getPosition());

        return user;
    }

    /**
     * 获取公司所有部门ID
     *
     * @param accessToken 调用接口凭证
     * @return
     */
    public List<Department> getAllDepertmentId(String accessToken) throws Exception {

        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
        OapiDepartmentListRequest request = new OapiDepartmentListRequest();
        request.setId("");
        request.setHttpMethod("GET");
        request.setFetchChild(true);

        OapiDepartmentListResponse response = client.execute(request, accessToken);

        List<OapiDepartmentListResponse.Department> departmentList = response.getDepartment();

        List<Department> depertmentList = new ArrayList<Department>();
        if (!CollectionUtils.isEmpty(departmentList)) {
            for (OapiDepartmentListResponse.Department department : departmentList) {

                Department newDepartment = new Department();

                long id = department.getId();
                Integer idd = (int) id;
                newDepartment.setId(idd);
                newDepartment.setDdId(department.getId() + "");
                newDepartment.setName(department.getName());
                newDepartment.setPid(department.getParentid() + "");

                depertmentList.add(newDepartment);

            }
        }


        return depertmentList;

        /*List<Object> depertmentIdList = new ArrayList<Object>();

        //1.获取请求url
        String url=GET_ALL_DEPARTMENT.replace("ACCESSTOKEN", accessToken).replace("DEPARTMENTID", "");

        JSONObject response = HttpHelper.httpGet(url);
        JSONArray jsonArray = response.getJSONArray("department");
        for (int i=0; i<jsonArray.size(); i++) {
            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            depertmentIdList.add(jsonObject.get("id").toString());
        }
        return depertmentIdList;*/
    }


    /**
     * 3.获取部门成员
     *
     * @param accessToken
     * @param departmentId
     * @throws Exception void
     * @desc ：
     */
    public void getDepartmentUser(String accessToken, Long departmentId) throws Exception {

        //1.获取请求url
        String url = GET_DEPARTMENTUSER_URL.replace("ACCESSTOKEN", accessToken).replace("DEPARTMENTID", departmentId + "");

        //2.发起GET请求，获取返回结果
        JSONObject jsonObject = HttpHelper.httpGet(url);
        System.out.println("jsonObject:" + jsonObject.toString());

        //3.解析结果，获取User
        if (null != jsonObject) {

            //4.错误消息处理
            if (0 != jsonObject.getInteger("errcode")) {
                int errCode = jsonObject.getInteger("errcode");
                String errMsg = jsonObject.getString("errmsg");
                throw new Exception("error code:" + errCode + ", error message:" + errMsg);
            }
        }
    }

    /**
     * 4.获取部门成员（详情）
     *
     * @param accessToken
     * @param departmentId
     * @throws Exception void
     * @desc ：
     */
    public List<User> getDepartmentUserDetail(String accessToken, Long departmentId, Long offset, Long size) throws Exception {


        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/listbypage");
        OapiUserListbypageRequest request = new OapiUserListbypageRequest();
        request.setDepartmentId(departmentId);
        request.setOffset(offset);
        request.setSize(size);
        request.setOrder("entry_desc");
        request.setHttpMethod("GET");
        OapiUserListbypageResponse execute = client.execute(request, accessToken);

        List<OapiUserListbypageResponse.Userlist> userlist = execute.getUserlist();

        List<User> list = new ArrayList<>();

        for (OapiUserListbypageResponse.Userlist ddUser : userlist) {

            User user = new User();
            user.setUsername(ddUser.getName());
            String department = ddUser.getDepartment();
            System.out.println(ddUser.getName() + "的部门字符串 getDepartmentUserDetail:" + department);
            String[] deptArr = StringUtils.strip(department, "[]").split(",");
            System.out.println(Arrays.toString(deptArr));
            int deptId = Integer.parseInt(deptArr[deptArr.length - 1].trim());

            user.setDeptId(deptId);
            user.setUserId(ddUser.getUserid());
            user.setPhone(ddUser.getMobile());
            user.setMail(ddUser.getEmail());

            Date date = ddUser.getHiredDate();
            if (!ObjectUtils.isEmpty(date)) {
                DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                Instant instant = date.toInstant();
                ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
                LocalDate localDate = zonedDateTime.toLocalDate();
                String format = localDate.format(timeFormatter);
                user.setHiredDate(format);

                int days = TimeUtil.getDifferentDays(date, new Date());
                String years = String.format("%.2f", Double.valueOf(days) / 365.0);
                user.setJobTime(years);
            }
            user.setPhoto(ddUser.getAvatar());
            user.setJob(ddUser.getPosition());

            list.add(user);


        }
        return list;
    }

    /**
     * 5.根据免登授权码Code查询免登用户userId
     *
     * @param accessToken
     * @param code
     * @throws Exception void
     * @desc ：钉钉服务器返回的用户信息为：
     * userid	员工在企业内的UserID
     * deviceId	手机设备号,由钉钉在安装时随机产生
     * is_sys	是否是管理员
     * sys_level	级别，0：非管理员 1：超级管理员（主管理员） 2：普通管理员（子管理员） 100：老板
     */
    public JSONObject getUserInfo(String accessToken, String code) throws Exception {

        //1.获取请求url
        String url = GET_USERINFO_BYCODE_URL.replace("ACCESSTOKEN", accessToken).replace("CODE", code);

        //2.发起GET请求，获取返回结果
        JSONObject jsonObject = HttpHelper.httpGet(url);
        System.out.println("jsonObject:" + jsonObject.toString());

        //3.解析结果，获取User
        if (null != jsonObject) {
            //4.请求成功,则返回jsonObject
            if (0 == jsonObject.getInteger("errcode")) {
                return jsonObject;
            }
            //5.错误消息处理
            if (0 != jsonObject.getInteger("errcode")) {
                int errCode = jsonObject.getInteger("errcode");
                String errMsg = jsonObject.getString("errmsg");
                throw new Exception("error code:" + errCode + ", error message:" + errMsg);
            }
        }

        return null;
    }

    @Override
    public Long getCompayEmpCount(String accessToken, Long ifActive) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get_org_user_count");
        OapiUserGetOrgUserCountRequest request = new OapiUserGetOrgUserCountRequest();
        request.setOnlyActive(ifActive);
        request.setHttpMethod("GET");
        OapiUserGetOrgUserCountResponse response = client.execute(request, accessToken);

        return response.getCount();
    }

    @Override
    public List<String> getUserIds(String accessToken, String departmentId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getDeptMember");
        OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
        req.setDeptId(departmentId);
        req.setHttpMethod("GET");
        OapiUserGetDeptMemberResponse rsp = client.execute(req, accessToken);
        return rsp.getUserIds();
    }

    @Override
    public List<UserDTO> getSmartWorkUserList(String accessToken, String userIds) throws ApiException, ParseException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/list");
        OapiSmartworkHrmEmployeeListRequest req = new OapiSmartworkHrmEmployeeListRequest();
        req.setUseridList(userIds);
        OapiSmartworkHrmEmployeeListResponse rsp = client.execute(req, accessToken);
        List<OapiSmartworkHrmEmployeeListResponse.EmpFieldInfoVO> result = rsp.getResult();
        List<UserDTO> list = new ArrayList<>();
        //遍历返回的所有用户
        for (OapiSmartworkHrmEmployeeListResponse.EmpFieldInfoVO empFieldInfoVO : result) {
            UserDTO user = new UserDTO();
            user.setUserId(empFieldInfoVO.getUserid());

            Edu edu = new Edu();
            //获取每个用户的花名册字段值
            List<OapiSmartworkHrmEmployeeListResponse.EmpFieldVO> fieldList = empFieldInfoVO.getFieldList();
            for (OapiSmartworkHrmEmployeeListResponse.EmpFieldVO empFieldVO : fieldList) {
                String fieldCode = empFieldVO.getFieldCode();
                String label = empFieldVO.getLabel();
                if ("sys00-name".equals(fieldCode)) {
                    user.setUsername(label);
                    System.out.println(label);
                } else if ("sys00-position".equals(fieldCode)) {
                    user.setJob(label);
                } else if ("sys00-mobile".equals(fieldCode)) {
                    user.setPhone(label);
                } else if ("sys00-email".equals(fieldCode)) {
                    user.setMail(label);
                    //身份证号
                } else if ("sys02-certNo".equals(fieldCode)) {
                    user.setCertNo(label);
                    //性别
                } else if ("sys02-sexType".equals(fieldCode)) {
                    if ("男".equals(label)) {
                        user.setSexType("1");
                    } else {
                        user.setSexType("0");
                    }

                    //入职时间
                } else if ("sys00-confirmJoinTime".equals(fieldCode)) {
                    if (!StringUtils.isEmpty(label)) {
                        user.setHiredDate(label);

                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        Date parse = sdf.parse(label);

                        int days = TimeUtil.getDifferentDays(parse, new Date());
                        String years = String.format("%.2f", Double.valueOf(days) / 365.0);
                        user.setJobTime(years);
                    }
                    //毕业院校
                } else if ("sys03-graduateSchool".equals(fieldCode)) {
                    edu.setSchool(label);
                    //毕业时间
                } else if ("sys03-graduationTime".equals(fieldCode)) {
                    edu.setGraTime(label);
                    //所学专业
                } else if ("sys03-major".equals(fieldCode)) {
                    edu.setMajor(label);
                    //最高学历
                } else if ("sys03-highestEdu".equals(fieldCode)) {
                    if ("大专".equals(label)) {
                        //0大专 1本科 2硕士 3博士
                        edu.setEduKind(0);
                    } else if ("本科".equals(label)) {
                        edu.setEduKind(1);
                    } else if ("硕士".equals(label)) {
                        edu.setEduKind(2);
                    } else if ("博士".equals(label)) {
                        edu.setEduKind(3);
                    } else {
                        edu.setEduKind(4);
                    }
                    //岗位职级
                } else if ("sys01-positionLevel".equals(fieldCode)) {
                    user.setJobTitle(label);
                } else if ("sys00-name".equals(fieldCode)) {
                    user.setUsername(label);
                } else if ("sys02-birthTime".equals(fieldCode)) {
                    user.setBirthday(label);
                } else if ("sys00-deptIds".equals(fieldCode)) {
                    if (!StringUtils.isEmpty(label)) {
                        String[] split = label.split("\\|");
                        int deptId = Integer.parseInt(split[split.length - 1].trim());
                        deptId = deptId == -1 ? 1 : deptId;
                        user.setDeptId(deptId);
                        //封装二级部门，如果没有二级部门，则封装一级部门
                        System.out.println("花名册返回的部门列表：" + Arrays.toString(split));

                        Integer threeDeptId = getSecondDeptId(deptId);
                        user.setSecondDeptId(threeDeptId);

                    }

                }
            }
            user.setEdu(edu);
            list.add(user);
        }
        return list;
    }

    /**
     * 根据部门id获取三级部门id
     *
     * @param id
     * @return
     */
    private Integer getSecondDeptId(Integer id) {
        //查询出二级部门id

        List<String> secondDeptIds = departmentMapper.getSecondDeptId("1");

        Integer threeDeptId = null;

        Department department = null;
        while (true) {
            department = departmentMapper.selectByPrimaryKey(id);

            if (secondDeptIds.contains(department.getPid())) {
                threeDeptId = department.getId();
                break;
            } else if ("1".equals(department.getPid())) {
                threeDeptId = department.getId();
                break;
            } else if (org.springframework.util.StringUtils.isEmpty(department.getPid()) || "null".equals(department.getPid())) {
                threeDeptId = department.getId();
                break;
            } else {
                id = Integer.parseInt(department.getPid());
            }
        }

        return threeDeptId;
    }

}
